package liurong.driver.jdk8;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.DoubleSummaryStatistics;
import java.util.HashMap;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class ListTest {

	public static void main(String... args) throws Exception {
		List<Person> personList = new ArrayList<>();
		// 自定义构造
		PersonFactory<Person> factory = Person::new;
		// 默认构造
		Supplier<Person> ad = Person::new;
		Person person2 = ad.get();

		personList.add(factory.createT("LI1", "HEN", 12));
		personList.add(factory.createT("LI2", "HEN", 56));
		personList.add(factory.createT("LI3", "HEN", 14));
		personList.add(factory.createT("LI4", "THE", 18));
		personList.add(factory.createT("LI5", "THE", 16));
		personList.add(factory.createT("LI6", "THE", 25));

		// 格式化1
		StringBuilder sb = new StringBuilder("[");
		for (Person person : personList) {
			if (sb.length() > 1)
				sb.append(",");
			sb.append(person.getFirstName());
		}
		sb.append("]");
		System.out.println(sb.toString());
		// [LI1,LI2,LI3,LI4,LI5,LI6]

		// 格式化2
		StringBuilder sb2 = new StringBuilder("[");
		personList.stream().map(Person::getFirstName).forEach(firstName -> {
			if (sb2.length() > 1)
				sb2.append(",");
			sb2.append(firstName);
		});
		sb2.append("]");
		System.out.println(sb2.toString());
		// [LI1,LI2,LI3,LI4,LI5,LI6]

		// 格式化3
		String result = personList.stream().map(Person::getFirstName).collect(Collectors.joining(",", "[", "]"));
		System.out.println(result);
		// [LI1,LI2,LI3,LI4,LI5,LI6]

		// 按照lastName分组
		Map<String, List<Person>> collect = personList.stream().collect(Collectors.groupingBy(Person::getLastName));
		System.out.println(collect);
		/*
		 * {THE=[Person{firstName='LI4', lastName='THE'},
		 * Person{firstName='LI5', lastName='THE'}, Person{firstName='LI6',
		 * lastName='THE'}], HEN=[Person{firstName='LI1', lastName='HEN'},
		 * Person{firstName='LI2', lastName='HEN'}, Person{firstName='LI3',
		 * lastName='HEN'}]}
		 */

		// 获取lastName分组后的的所有firstName集合 简单方式
		Map<String, List<String>> nameOfListFirstName = new HashMap<>();
		for (Map.Entry<String, List<Person>> entry : collect.entrySet()) {
			nameOfListFirstName.put(entry.getKey(),
					entry.getValue().stream().map(Person::getFirstName).collect(Collectors.toList()));
		}
		System.out.println(nameOfListFirstName);
		// {THE=[LI4, LI5, LI6], HEN=[LI1, LI2, LI3]}

		// 收集器方式 最外层groupingBy分组,接着按firstName进行统计并放入集合
		Map<String, List<String>> nameOfListFirstName2 = personList.stream().collect(Collectors
				.groupingBy(Person::getLastName, Collectors.mapping(Person::getFirstName, Collectors.toList())));

		System.out.println(nameOfListFirstName2);

		// 按照lastName分组并统计其数量
		Map<String, Long> map = personList.stream()
				.collect(Collectors.groupingBy(Person::getLastName, Collectors.counting()));
		System.out.println(map);
		// {THE=3, HEN=3}

		// 对年龄进行统计
		// double格式的结果
		DoubleSummaryStatistics doubleSummaryStatistics = personList.stream().map(person -> person.getAge() + 1)
				.collect(Collectors.summarizingDouble(value -> value));
		// DoubleSummaryStatistics{count=6, sum=147.000000, min=13.000000,
		// average=24.500000, max=57.000000}
		System.out.println(doubleSummaryStatistics);
		System.out.println(doubleSummaryStatistics.getAverage());
		System.out.println(doubleSummaryStatistics.getMax());
		System.out.println(doubleSummaryStatistics.getCount());

		// int格式的结果 还有其他long等类型
		IntSummaryStatistics intSummaryStatistics = personList.stream().map(person -> person.getAge())
				.collect(Collectors.summarizingInt(value -> value));

		System.out.println(intSummaryStatistics);
		// IntSummaryStatistics{count=6, sum=141, min=12, average=23.500000,
		// max=56}

		// 求平均值

		Double dAvg = personList.stream().map(Person::getAge).collect(Collectors.averagingDouble(value -> value)); // 将值加一

		System.out.println(dAvg);

		// 根据List创建Map

		List<Integer> list = IntStream.range(1, 10).boxed().collect(Collectors.toList());// 生成1到9
		System.out.println(list);
		// [1, 2, 3, 4, 5, 6, 7, 8, 9]
		Map<Integer, Integer> _map = list.stream().sorted((a, b) -> a.compareTo(b))
				.collect(Collectors.toMap(p -> p, q -> q * 3));
		System.out.println(_map);
		// {1=3, 2=6, 3=9, 4=12, 5=15, 6=18, 7=21, 8=24, 9=27}

		// 求最大值
		List<Integer> list2 = new Random().ints(-100, 100).limit(250).boxed().collect(Collectors.toList());
		Optional<Integer> max = list.stream().reduce(Math::max);
		max.ifPresent(value -> System.out.println(value));

		// 把所有的姓名大写、排序，再输出

		String[] names = { "Fred Edwards", "Anna Cox", "Deborah Patterson", "Ruth Torres", "Shawn Powell",
				"Rose Thompson", "Rachel Barnes", "Eugene Ramirez", "Earl Flores", "Janice Reed", "Sarah Miller",
				"Patricia Kelly", "Carl Hall", "Craig Wright", "Martha Phillips", "Thomas Howard", "Steve Martinez",
				"Diana Bailey", "Kathleen Hughes", "Russell Anderson", "Theresa Perry" };
		Arrays.asList(names).stream().map(String::toUpperCase).sorted().forEach(System.out::println);

	}
}

// 定义创建对象接口
interface PersonFactory<P extends Person> {
	P createT(String firstName, String lastName, int age);
}